package org.ainlolcat.ainscience.statistics.handlers.hitran.tests;

import org.ainlolcat.ainscience.statistics.handlers.hitran.SpectrGenerator;
import org.ainlolcat.ainscience.statistics.handlers.hitran.instfunc.InstrumentalFunction;
import org.ainlolcat.ainscience.statistics.handlers.hitran.instfunc.PsdVoigt1InstrumentalFunction;
import org.ainlolcat.ainscience.statistics.handlers.hitran.sobx.BxSpectrTemperatureFinder;
import org.math.plot.Plot2DPanel;

import javax.swing.*;
import java.io.IOException;

/**
 * @author ainlolcat
 * Date: 12/12/11
 */
public class testSpectrStatistic {

    //static double if_A=35664.07, if_w=1.51335,  if_y0=0; //ava2048-2 bc600mk 738nm
	//static double if_A=22478.48, if_w=0.52113,  if_y0=0; //ava2048-1 bc600mk 772nm
    static double if_A=1.67E12, if_w=0.60814,  if_y0=3.39E9,  if_mu = 0.07335; //ava2048-1 bc600mk 772nm
    static InstrumentalFunction function = new PsdVoigt1InstrumentalFunction(if_w, if_mu);

    public static void main(String[] args) throws IOException {
        plotBx();
        plotTbDX();
        //testBxDx();
    }

    public static void plotTbDX() throws IOException {
        int dots = 40;
        int start = -40;
        int dx = 2;
        double baseT = 300;
        double[] x = new double[dots];
        double[] y = new double[dots];

        for (int i=0;i<dots;i++){

            x[i] = start + dx*i;

            double[][] spectr = generateBxSpectr(baseT);
            //multiple on smth
            double multiplicator= 1E5 * Math.random();
            for (int j=0;j<spectr.length;j++){
                spectr[j][1] = spectr[j][1]*multiplicator;
            }
            //lets add noise
            double max = spectr[0][1];
            for (int j=0;j<spectr.length;j++){
                if (spectr[j][1]>max) max = spectr[j][1];
            }
            float whiteNoiseLevel= 0.03f;
            for (int j=0;j<spectr.length;j++){
                spectr[j][1] = spectr[j][1] + 2*(Math.random()-0.5) * whiteNoiseLevel * max;
            }
            //move a bit
            if (x[i]>0){
                for (int j=0;j<spectr.length-x[i];j++){
                    spectr[j][1] = spectr[j+(int)x[i]][1];
                }
            }else {
                for (int j=spectr.length-1;j>-x[i];j--){
                    spectr[j][1] = spectr[j+(int)x[i]][1];
                }
            }

            y[i] = getBxT(spectr);

        }

        Plot2DPanel plot = new Plot2DPanel();
        plot.addLinePlot("",x,y);
        JFrame frame = new JFrame("a plot panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setContentPane(plot);
        frame.setVisible(true);
    }

    public static void testBxDx() throws IOException {
        double[][] spect = generateBxSpectr(300);
        int dx = 100;
        for (int i=0;i<spect.length-dx;i++){
            spect[i][1] = spect[i+dx][1];
        }
        System.out.println("For dx = "+dx+" : "+getBxT(spect));

        spect = generateBxSpectr(300);
        dx = -100;
        for (int i=spect.length-1;i>-dx;i--){
            spect[i][1] = spect[i+dx][1];
        }
        System.out.println("For dx = "+dx+" : "+getBxT(spect));

        spect = generateBxSpectr(300);
        System.out.println("For dx = "+0+" : "+getBxT(spect));
    }

    public static void plotBx() throws IOException {
        double baseT = 300;
        double[][] spect = generateBxSpectr(baseT);
        double[] x = new double[spect.length];
        double[] y = new double[spect.length];
        for (int i=0;i<x.length;i++){
            x[i] = spect[i][0];
            y[i] = spect[i][1];
        }


        //multiple on smth
        double multiplicator= 1E10 * Math.random();
        for (int j=0;j<y.length;j++){
            y[j] = y[j]*multiplicator;
        }
        //lets add noise
        double max = y[0];
        for (int j=0;j<y.length;j++){
            if (y[j]>max) max = y[j];
        }
        float whiteNoiseLevel= 0.03f;
        for (int j=0;j<y.length;j++){
            y[j] = y[j] + 2*(Math.random()-0.5) * whiteNoiseLevel * max;
        }

        for (int j=0;j<y.length-10;j++){
            y[j] = y[j+10];
        }



        double[] y2 = getBxSpectr(baseT,x,y);
        //lets normalize
        double max2 = y2[0];
        for (int j=0;j<y2.length;j++){
            if (y2[j]>max2) max2 = y2[j];
        }
        for (int j=0;j<y.length;j++){
            y2[j] = y2[j]*max/max2;
        }

        double resT = getBxT(x,y);
        double[] y3 = getBxSpectr(resT,x,y);
        //lets normalize
        double max3 = y3[0];
        for (int j=0;j<y3.length;j++){
            if (y3[j]>max3) max3 = y3[j];
        }
        for (int j=0;j<y3.length;j++){
            y3[j] = y3[j]*max/max3;
        }


        Plot2DPanel plot = new Plot2DPanel();
        plot.addLinePlot("changed source",x,y);
        plot.addLinePlot("generated",x,y2);
        plot.addLinePlot("PC choice",x,y3);
        plot.setLegendOrientation("LEFT");
        JFrame frame = new JFrame("a plot panel");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(600, 600);
        frame.setContentPane(plot);
        frame.setVisible(true);

        System.out.println(resT);
    }

    public static double getBxT(double[][] spectr) throws IOException {
        BxSpectrTemperatureFinder bxf = new BxSpectrTemperatureFinder();
        double[] x = new double[spectr.length];
        double[] y = new double[spectr.length];
        for (int i=0;i<x.length;i++){
            x[i] = spectr[i][0];
            y[i] = spectr[i][1];
        }
        return bxf.getT(x,y,function,240,360,1);
    }

    public static double getBxT(double[] x,double[] y) throws IOException {
        BxSpectrTemperatureFinder bxf = new BxSpectrTemperatureFinder();
        return bxf.getT(x,y,function,240,360,1);
    }

    public static double[][] generateBxSpectr(double T) throws IOException {
        SpectrGenerator sg = new SpectrGenerator();
        return sg.getBxSpectr(T, function, 750, 780, 0.25);
    }

    public static double[] getBxSpectr(double T, double[] x, double[] y) throws IOException {
        SpectrGenerator sg = new SpectrGenerator();
        return sg.getBxSpectr(T, function, x, y);
    }
}
